/**
 * @(#) NXTActuator.java
 */

package pcsr.drivers.nxtDriver;

import pcsr.drivers.nxtDriver.command.INXTCommand;
import pcsr.drivers.nxtDriver.command.OutputState;

abstract class NXTActuator implements INXTActuator
{
	public int blockTachoCount; // Current position relative to last programmed movement
	
	public int rotationCount; // Current position relative to last reset of the rotation sensor for this motor)
	
	public byte status; // Status of the NXTCommand.getOutputState command.
	
	public int tachoCount; // Internal count. Number of counts since last reset of the motor counter)
	
	public long tachoLimit; // Current limit on a movement in progress, if any
	
	public byte turnRatio;
	
	private INXTCommand btCommandManager;

	private NXTActuatorMode mode;
	
	private NXTPort port;
	
	private byte power;
	
	private NXTActuatorRegulationMode regulationMode;
	
	private NXTActuatorRunState runState = NXTActuatorRunState.RUNNING;
	
	protected NXTActuator( NXTPort motor, INXTCommand nxtCommand ) {
		SetPort(motor);		
		btCommandManager = nxtCommand;
	}
	
	public abstract NXTActuatorMode[] GetAvailableModes( );
	
	@Override
	public NXTActuatorMode GetMode( ) {
		return mode;
	}

	public byte GetPower( ) {
		return power;
	}

	@Override
	public NXTActuatorRegulationMode GetRegulationMode( ) {
		return regulationMode;
	}

	@Override
	public NXTActuatorRunState GetRunState( ) {
		return runState;
	}

	@Override
	public void SetMode( NXTActuatorMode newmode ) {
		mode = newmode;
	}
	
	public void SetPower( byte powerSetpoint ) {
		power = powerSetpoint;
	}
	
	@Override
	public void SetRegulationMode( NXTActuatorRegulationMode newregulationMode ) {
		regulationMode = newregulationMode;
	}
	
	@Override
	public void SetRunState( NXTActuatorRunState newrunState ) {
		runState = newrunState; 
	}

	/**
	 * Gets actuator state from the robot.
	 * @return 0 - success
	 */
	protected synchronized int UpdateActuatorState( )
	{
		OutputState output = btCommandManager.GetOutputState(GetPort().GetPortID());
				
		status = output.status;		
		SetPower(output.powerSetpoint);		
		SetMode(NXTActuatorMode.GetModeByValue(output.mode));		
		SetRegulationMode(NXTActuatorRegulationMode.GetRegulationModeByValue(output.regulationMode));		
		SetTurnRatio(output.turnRatio);			
		SetRunState(NXTActuatorRunState.GetRunStateByValue(output.runState));		
		SetTachoLimit(output.tachoLimit);		
		tachoCount = output.tachoCount;
		blockTachoCount = output.blockTachoCount; 
		rotationCount = output.rotationCount; 

		return 0;
	}

	long GetTachoLimit( ) {
		return tachoLimit;
	}

	byte GetTurnRatio( ) {
		return turnRatio;
	}

	/**
	 * Sets actuator state into the robot.
	 * @return 0 - success
	 */
	protected synchronized int SetActuatorState( )
	{
		return btCommandManager.SetOutputState(
					GetPort().GetPortID(), 
					GetPower(), 
					GetMode().GetModeID(), 
					GetRegulationMode().GetRegulationModeValue(), 
					GetTurnRatio(), 
					GetRunState().GetRunStateValue(),
					0
				);
	}

	void SetTachoLimit( long newtachoLimit ) {
		tachoLimit = newtachoLimit;
	}

	void SetTurnRatio( byte newturnRatio ) {
		turnRatio = newturnRatio;
	}

	/**
	 * @param port the port to set
	 */
	void SetPort( NXTPort port ) {
		this.port = port;
	}

	/**
	 * @return the port
	 */
	public NXTPort GetPort( ) {
		return port;
	}
}
